# vnpy_advice/utils/data_utils.py
from typing import List, Optional, Union
import pandas as pd
from datetime import datetime
from vnpy.trader.object import BarData, HistoryRequest
from vnpy.trader.constant import Exchange, Interval
from vnpy.trader.database import get_database
from vnpy_tushare.tushare_datafeed import TushareDatafeed
from vnpy.trader.setting import SETTINGS

def convert_to_bar_data(historical_data: pd.DataFrame) -> List[BarData]:
    """将输入的历史数据转换为vnpy的BarData格式
    
    Args:
        historical_data: DataFrame格式，包含open/high/low/close/volume等字段
        
    Returns:
        List[BarData]: 转换后的K线数据列表
    """
    bars = []
    for idx, row in historical_data.iterrows():
        # 处理datetime字段的格式转换
        dt = parse_datetime(row["datetime"])
            
        # 处理交易所信息
        exchange = parse_exchange(row["exchange"])
            
        bar = BarData(
            symbol=str(row["symbol"]),
            exchange=exchange,
            datetime=dt,
            open_price=float(row["open_price"]),
            high_price=float(row["high_price"]),
            low_price=float(row["low_price"]),
            close_price=float(row["close_price"]),
            volume=float(row["volume"]),
            gateway_name="CTP"
        )
        bars.append(bar)
    return bars

def parse_datetime(dt_field: Union[str, datetime, pd.Timestamp]) -> datetime:
    """解析日期时间字段
    
    Args:
        dt_field: 日期时间字段，可能是字符串、datetime或Timestamp
        
    Returns:
        datetime: 转换后的datetime对象
    """
    if isinstance(dt_field, str):
        return datetime.strptime(dt_field, "%Y-%m-%d %H:%M:%S")
    elif isinstance(dt_field, pd.Timestamp):
        return dt_field.to_pydatetime()
    return dt_field

def parse_exchange(exchange_input):
    """解析交易所字段
    
    Args:
        exchange_input: 交易所字符串或 Exchange 枚举值
        
    Returns:
        Exchange: vnpy的Exchange枚举值
    """
    exchange_map = {
        "SSE": Exchange.SSE,
        "SZSE": Exchange.SZSE,
        "CFFEX": Exchange.CFFEX,
        "SHFE": Exchange.SHFE,
        "DCE": Exchange.DCE,
        "CZCE": Exchange.CZCE,
    }
    
    if isinstance(exchange_input, str):
        return exchange_map.get(exchange_input.upper(), Exchange.SSE)
    elif isinstance(exchange_input, Exchange):
        return exchange_input
    else:
        return Exchange.SSE

def validate_market_data(df: pd.DataFrame) -> bool:
    """验证市场数据的完整性
    
    Args:
        df: 输入的DataFrame
        
    Returns:
        bool: 数据是否有效
    """
    required_columns = ["datetime", "symbol", "exchange", "open", "high", "low", "close", "volume"]
    return all(col in df.columns for col in required_columns)

def load_market_data(
    symbol: str,
    exchange: Exchange,
    start: datetime,
    end: datetime,
    interval: Interval = Interval.DAILY,
    use_database: bool = True
) -> List[BarData]:
    """加载市场数据"""
    if use_database:
        # 首先尝试从数据库加载
        database = get_database()
        data = database.load_bar_data(
            symbol=symbol,
            exchange=exchange,
            interval=interval,
            start=start,
            end=end
        )
        if data:
            return data
    
    # 如果数据库中没有数据，则从Tushare获取
    SETTINGS['datafeed.username'] = "token"
    SETTINGS['datafeed.password'] = "600713cc777ee2505142620a527eebe2c27a973b5fe89fce9fe8f07f"
    tushare_feed = TushareDatafeed()
    
    # 创建请求对象
    req = HistoryRequest(
        symbol=symbol,
        exchange=exchange,
        interval=interval,
        start=start,
        end=end
    )
    
    # 查询数据
    data = tushare_feed.query_bar_history(req)
    
    # 保存到数据库
    if data and use_database:
        database = get_database()
        database.save_bar_data(data)
    
    return data